package com.bsj.power.common.http;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.bsj.power.common.config.cached.RedisCached;
import com.bsj.power.common.config.redis.RedisConstant;
import com.bsj.power.common.def.http.dto.LocalServerKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;

/**
 * @author yinhao
 * @version 1.0
 * @description 人员登录信息同步HTTP方法
 * @date 2024/7/15
 */
@Slf4j
@Component
public class LoginPersonHttp {

    @Autowired
    private RedisCached redisCached;

    /**
     * 第一步：
     * <p>
     * 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息
     */
    public Map<String, Object> testRegist(String address, String APPID) {

        //获取当前系统RSA加密的公钥
        RSA rsa = new RSA();
        String publicKey = rsa.getPublicKeyBase64();
        String privateKey = rsa.getPrivateKeyBase64();

        // 客户端RSA私钥
//        SYSTEM_CACHE.put("LOCAL_PRIVATE_KEY", privateKey);
        // 客户端RSA公钥
//        SYSTEM_CACHE.put("LOCAL_PUBLIC_KEY", publicKey);
        LocalServerKey localServerKey = new LocalServerKey();

        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(address + "/api/ec/dev/auth/regist")
                .header("appid", APPID)
                .header("cpk", publicKey)
                .timeout(2000)
                .execute().body();

        // 打印ECOLOGY响应信息
        log.info("testRegist()： {}", data);
        Map<String, Object> datas = JSONUtil.parseObj(data);

        //ECOLOGY返回的系统公钥
//        SYSTEM_CACHE.put("SERVER_PUBLIC_KEY", StrUtil.nullToEmpty((String)datas.get("spk")));
        //ECOLOGY返回的系统密钥
//        SYSTEM_CACHE.put("SERVER_SECRET", StrUtil.nullToEmpty((String)datas.get("secrit")));
        if ((Integer)datas.get("code") == 0) {
            localServerKey.setLocalPublicKey(publicKey);
            localServerKey.setLocalPrivateKey(privateKey);
            localServerKey.setServerPublicKey((String) datas.get("spk"));
            localServerKey.setServerSecret((String) datas.get("secrit"));
            redisCached.set(RedisConstant.LOGIN_PERSON_ECOLOGY,localServerKey);
        }
        return datas;
    }

    /**
     * 第二步：
     * <p>
     * 通过第一步中注册系统返回信息进行获取token信息
     */
    public Map<String, Object> testGetoken(String address, String APPID) {
        String localServer = redisCached.get(RedisConstant.LOGIN_PERSON_ECOLOGY);
        if (Objects.isNull(localServer)) {
            testRegist(address, APPID);
            localServer = redisCached.get(RedisConstant.LOGIN_PERSON_ECOLOGY);
        }
        LocalServerKey localServerKey = JSON.parseObject(localServer, LocalServerKey.class);
        // 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
        String secret = localServerKey.getServerSecret();
        String spk = localServerKey.getServerPublicKey();

        // 公钥加密,所以RSA对象私钥为null
        RSA rsa = new RSA(null, spk);
        //对秘钥进行加密传输，防止篡改数据
        String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);

        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(address + "/api/ec/dev/auth/applytoken")
                .header("appid", APPID)
                .header("secret", encryptSecret)
                .header("time", "3600")
                .execute().body();

        log.info("testGetoken()： {}", data);
        Map<String, Object> datas = JSONUtil.parseObj(data);

        //ECOLOGY返回的token
        // TODO 为Token缓存设置过期时间为 10分钟
//        SYSTEM_CACHE.put("SERVER_TOKEN", StrUtil.nullToEmpty((String) datas.get("token")));
        redisCached.set(RedisConstant.LOGIN_PERSON_ECOLOGY_TOKEN, (String) datas.get("token"), 60 * 10);
        return datas;
    }

    /**
     * 第三步：
     * <p>
     * 调用ecology系统的rest接口，请求头部带上token和用户标识认证信息
     *
     * @param address    ecology系统地址
     * @param api        rest api 接口地址(该测试代码仅支持GET请求)
     * @param jsonParams 请求参数json串
     *                   <p>
     *                   注意：ECOLOGY系统所有POST接口调用请求头请设置 "Content-Type","application/x-www-form-urlencoded; charset=utf-8"
     */
    public String postRestful(String address, String api, String jsonParams, String APPID) {

        String token = redisCached.get(RedisConstant.LOGIN_PERSON_ECOLOGY_TOKEN);
        //ECOLOGY返回的token
//        String token = SYSTEM_CACHE.get("SERVER_TOKEN");
        if (StrUtil.isEmpty(token)) {
            token = (String) testGetoken(address, APPID).get("token");
        }

        String localServer = redisCached.get(RedisConstant.LOGIN_PERSON_ECOLOGY);
        LocalServerKey localServerKey = JSON.parseObject(localServer, LocalServerKey.class);

//        String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
        String spk = localServerKey.getServerPublicKey();
        //封装请求头参数
        RSA rsa = new RSA(null, spk);
        //对用户信息进行加密传输,暂仅支持传输OA用户ID
        String encryptUserid = rsa.encryptBase64("1", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);

        //调用ECOLOGY系统接口
        String data = HttpRequest.post(address + api)
                .header("appid", APPID)
                .header("token", token)
                .header("userid", encryptUserid)
                .header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
                .body(jsonParams)
                .execute().body();
        log.info("postRestful()： {}", data);
        return data;
    }
}
